package icbc.nav.control
{
	import com.greensock.TweenLite;
	import com.greensock.easing.Strong;
	
	import flash.display.DisplayObject;
	import flash.display.GradientType;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.display.SpreadMethod;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.MouseEvent;
	import flash.filters.BevelFilter;
	import flash.filters.DropShadowFilter;
	import flash.filters.GlowFilter;
	import flash.geom.Matrix;
	import flash.net.URLRequest;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
	
	import icbc.app.AppGlobal;
	
	import org.osflash.signals.Signal;
	
	public class MenuButton extends Sprite
	{
		public static const EVENT_CLICK:String = "HELPBUTTON_EVENT_CLICK";
		public static const STATE_NORMAL:uint = 0;
		public static const STATE_CLICKED:uint = 1;
		public static const STYLE_ROOT:uint = 0;
		public static const STYLE_CHILD:uint = 1;
		private static const TXT_CHILD_NAME:String = "txt";
		private static const FONT_COLOR:uint = 0xE381B2;
		private static const ICON_WIDTH:uint = 39;
		private static const TEXT_HEIGHT:uint = 27;
		private static const ARROW_WIDTH:uint = 4;
		private static const ARROW_HEIGHT:uint = 10;
		private static const MARGIN_ARROW_X:uint = 7;
		public static const TYPE_UP:uint = 0;
		public static const TYPE_MIDDLE:uint = 1;
		public static const TYPE_BOTTOM:uint = 2;
		private var buttonType:uint = 0;
		private var gap:uint = 5;
		public var data:Object;
		private var controlWidth:uint;
		private var controlHeight:uint;
		private var icon:Sprite;
		private var rounded:uint = 20;
		public var state:uint = 0;
		private var baseRedColor:uint = 0xC52027;
		private var borderColor:uint = 0xAAAAAA;
		
		private var main:Sprite = new Sprite();
		private var base:Sprite = new Sprite();
		private var over:Sprite = new Sprite();
		private var press:Sprite = new Sprite();
		private var clicked:Sprite = new Sprite();
		private var panel:Sprite;
		private var style:uint = STYLE_CHILD;
		
		public var onClicked:Signal = new Signal(MenuButton);

		public function MenuButton(data:Object, vWidth:uint, vHeight:uint, style:uint = 1, buttonType:uint = 0)
		{
			super();
			this.data = data;
			this.style = style;
			this.controlWidth = vWidth;
			this.controlHeight = vHeight;
			this.buttonType = buttonType;
			addChild(main);
			main.addChild(base);
			main.addChild(over);
			main.addChild(clicked);
			main.addChild(press);
			addEventListener(Event.ADDED_TO_STAGE, initStage);
		}
		
		private function initStage(evt:Event):void
		{
			removeEventListener(Event.ADDED_TO_STAGE, initStage);
			display();
		}
		
		private function display():void
		{
			buildBase();
			buildOver();
			buildClicked();
			buildPress();
			addListeners();
		}

		private function build(item:Sprite, colors:Array, textColor:uint = 0x1f416c):void
		{
			switch(style)
			{
				case STYLE_ROOT:
				{
					setRootBase(item, colors, textColor);
					break;
				}
				case STYLE_CHILD:
				{
					setListItemBase(item, colors, textColor);
					break;
				}
				default:
				{
					break;
				}
			}
		}

		private function setListItemBase(item:Sprite, colors:Array, textColor:uint = 0x1f416c):void
		{
			item.graphics.beginFill(0xffffff);
			item.graphics.drawRect(0, 0, controlWidth, controlHeight);
			item.graphics.endFill();

			item.graphics.lineStyle(0.5, borderColor);

			item.graphics.moveTo(0,0);
			if(buttonType == TYPE_MIDDLE || buttonType == TYPE_BOTTOM)
			{
				item.graphics.moveTo(controlWidth,0);
			} else {
				item.graphics.lineTo(controlWidth,0);
			}
			item.graphics.lineTo(controlWidth,controlHeight);
			if(buttonType == TYPE_UP || buttonType == TYPE_MIDDLE)
			{
				item.graphics.moveTo(0,controlHeight);
			} else {
				item.graphics.lineTo(0,controlHeight);
			}
			item.graphics.lineTo(0,0);
			if(buttonType == TYPE_MIDDLE || buttonType == TYPE_UP)
			{
				var lineGap:uint = 10;
				var linePosy:uint = controlHeight-1;
				item.graphics.lineStyle(1, borderColor);
				item.graphics.moveTo(lineGap, linePosy);
				item.graphics.lineTo(controlWidth-lineGap, linePosy);
			}
			
			var arrow:Sprite = buildArrow(textColor);
			item.addChild(arrow);
			arrow.x = controlWidth - arrow.width - MARGIN_ARROW_X;
			arrow.y = controlHeight/2 - arrow.height/2;
			
			var itemtxt:TextField = buildText( {
				width : controlWidth,
				height : 18,
				text : data.label,
				color : textColor
			} );
			itemtxt.name = TXT_CHILD_NAME;
			item.addChild(itemtxt);

			var posx:int = controlWidth/2 - itemtxt.width/2;
			if(style == STYLE_CHILD)
			{
				posx = 10;
			}
			itemtxt.x = posx;
			itemtxt.y = controlHeight/2 - itemtxt.height/2;
			item.alpha = 0;
		}

		private function setRootBase(item:Sprite, colors:Array, textColor:uint = 0x1f416c):void
		{
			var rounded:uint = 0;
			var alphas:Array = [ 1, 1, 1 ];
			var ratios:Array = [ 0x00, 0xF5, 0xFF ];
			var matrix:Matrix = new Matrix();
			matrix.createGradientBox(controlWidth, controlHeight, (Math.PI / 2), 0, 0);
			item.graphics.lineStyle(0, 0xDDDDDD);
			item.graphics.beginGradientFill(GradientType.LINEAR, colors, alphas, ratios, matrix, SpreadMethod.PAD);
			item.graphics.drawRoundRect(0, 0, controlWidth, controlHeight, rounded, rounded);
			item.graphics.endFill();
			
			var itemtxt:TextField = buildText( {
				width : controlWidth,
				height : 18,
				text : data.label,
				color : textColor
			} );
			var txtFilterD:DropShadowFilter = new DropShadowFilter(1, 45, 0x999999, 1, 1, 1, 1, 3, false, false, false);
			itemtxt.filters = [txtFilterD];
			itemtxt.name = TXT_CHILD_NAME;
			item.addChild(itemtxt);
			itemtxt.x = controlWidth/2 - itemtxt.width/2;
			itemtxt.y = controlHeight/2 - itemtxt.height/2;
			item.alpha = 0;
		}
		
		private function buildText(config:Object) : TextField
		{
			var textSize:uint = AppGlobal.FONT_SIZE;
			var textAlign:String = "center";
			var autoSize:String = TextFieldAutoSize.CENTER;
			if(style == STYLE_CHILD)
			{
				textSize = AppGlobal.FONT_SMALL_SIZE;
				textAlign = "left";
				autoSize = TextFieldAutoSize.LEFT;
			}
			var text:String = (config.text != undefined)?config.text:"";
			var width:uint = (config.width != undefined)?config.width:120;
			var height:uint = (config.height != undefined)?config.height:18;
			var color:uint = (config.color != undefined)?config.color:0xffffff;
			var format:TextFormat = new TextFormat();
			format.font = AppGlobal.FONT_NAME;
			format.color = color;
			format.size = textSize;
			format.align = textAlign;
			var txt:TextField = new TextField();
			txt.selectable = false;
			txt.defaultTextFormat = format;
			txt.autoSize = autoSize;
			txt.text = text;
			return txt;
		}
		
		private function addListeners():void
		{
			press.addEventListener(MouseEvent.MOUSE_OVER, onRollOver);
			press.addEventListener(MouseEvent.MOUSE_OUT, onRollOut);
			press.addEventListener(MouseEvent.MOUSE_DOWN, onPress);
			press.addEventListener(MouseEvent.MOUSE_UP, onRelease);
		}
		
		private function removeListeners():void
		{
			press.removeEventListener(MouseEvent.MOUSE_OVER, onRollOver);
			press.removeEventListener(MouseEvent.MOUSE_OUT, onRollOut);
			press.removeEventListener(MouseEvent.MOUSE_DOWN, onPress);
			press.removeEventListener(MouseEvent.MOUSE_UP, onRelease);
		}
		
		private function onRollOver(evt:Event):void
		{
			var tween:TweenLite = new TweenLite(over,1,{ease:Strong.easeOut,alpha:1});
		}
		
		private function onRollOut(evt:Event):void
		{
			var tween:TweenLite = new TweenLite(over,2,{ease:Strong.easeOut,alpha:0});
			press.alpha = 0;
		}
		
		private function onPress(evt:Event):void
		{
			var tween:TweenLite = new TweenLite(press,0.5,{ease:Strong.easeOut,alpha:1});
		}
		
		private function onRelease(evt:Event):void
		{
			var tween:TweenLite = new TweenLite(press,1,{ease:Strong.easeOut,alpha:0});
			dispatchEvent(new Event(EVENT_CLICK));
			onClicked.dispatch(this);
			clicked.alpha = 1;
			state = STATE_CLICKED;
		}
		
		private function buildBase():void
		{
			build(base, [0xffffff, 0xffffff, 0xefefef], 0x8A8C8E);
			base.alpha = 1;
		}
		
		private function buildOver() : void
		{
			var textColor:uint = 0xffffff;
			if(style == STYLE_CHILD)
			{
				textColor = AppGlobal.RED_ICBC;
			}
			build(over, [0x7fb2ea, 0x2267d1, 0x1a64c1], textColor);
		}
		
		private function buildClicked() : void
		{
			var textColor:uint = 0xffffff;
			if(style == STYLE_CHILD)
			{
				textColor = baseRedColor;
			}
			build(clicked, [0xA8A8AA, 0x616061, 0x282928], textColor);
			if(style == STYLE_ROOT)
			{
				clicked.visible = false;
			}
		}
		
		private function buildPress() : void
		{
			var textColor:uint = 0xffffff;
			if(style == STYLE_CHILD)
			{
				textColor = AppGlobal.RED_ICBC;
			}
			build(press, [0xA8A8AA, 0x616061, 0x282928], textColor);
		}
		
		private function buildIcon():void
		{
			if(data.icon == null || data.icon == "")
			{
				return;
			}
			var iconPath:String = data.icon;
			var loader:Loader = new Loader();
			loader.contentLoaderInfo.addEventListener(Event.COMPLETE, imageComplete);
			loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
			loader.load(new URLRequest(iconPath));
			icon.addChild(loader);
		}
		
		private function onIOError(evt:IOErrorEvent):void
		{
			trace("MenuButton.Image["+ data.icon +"].IOError: "+ evt.text);
		}		
		
		private function imageComplete(evt:Event):void
		{
			var image:DisplayObject = (evt.target as LoaderInfo).content;
			icon.y = controlHeight/2 - image.height/2;
		}

		public function dispose():void
		{
			removeListeners();
		}
		
		public function clearState():void
		{
			clicked.alpha = 0;
			state = STATE_NORMAL;
		}
		
		public function buildArrow(color:uint):Sprite
		{
			var sprite:Sprite = new Sprite();
			sprite.graphics.lineStyle(1, color);
			sprite.graphics.lineTo(0,0);
			sprite.graphics.lineTo(ARROW_WIDTH,ARROW_HEIGHT/2);
			sprite.graphics.lineTo(0,ARROW_HEIGHT);
			return sprite;
		}
	}
}